namespace RBAC.Read.Api.Application.Handler.BomHandler
{
    using MediatR;
    using Microsoft.Extensions.Logging;
    using RBAC.Domain.BomManage;
    using RBAC.ErrorCode;
    using RBAC.Interstructrue.Base;
    using RBAC.Read.Api.Application.Command.BomCommand;
    using RBAC.Read.Api.Application.Dto.Bom;

    /// <summary>
    /// BOM 分页查询处理器（无条件），补充产品编码与名称
    /// </summary>
    public class GetBomListHandler : IRequestHandler<GetBomListCommand, APIPaging<BomListItemDto>>
    {
        private readonly IBaseRepository<Bom> bomRepository;
        private readonly IBaseRepository<Product> productRepository;
        private readonly ILogger<GetBomListHandler> logger;

        public GetBomListHandler(IBaseRepository<Bom> bomRepository, IBaseRepository<Product> productRepository, ILogger<GetBomListHandler> logger)
        {
            this.bomRepository = bomRepository;
            this.productRepository = productRepository;
            this.logger = logger;
        }

        /// <summary>
        /// 处理 BOM 无条件分页查询请求。
        /// - 校验页码与页大小
        /// - 批量补充产品编码与名称
        /// - 分别处理取消异常与一般异常
        /// </summary>
        public Task<APIPaging<BomListItemDto>> Handle(GetBomListCommand request, CancellationToken cancellationToken)
        {
            var result = new APIPaging<BomListItemDto>();
            try
            {
                cancellationToken.ThrowIfCancellationRequested();

                if (request.PageIndex <= 0) request.PageIndex = 1;
                if (request.PageSize <= 0) request.PageSize = 10;

                logger.LogInformation("开始获取BOM分页 PageIndex={PageIndex}, PageSize={PageSize}", request.PageIndex, request.PageSize);

                var (boms, total) = bomRepository.GetPaged(request.PageIndex, request.PageSize, string.Empty, request.OrderBy, null);

                // 批量查询产品信息
                var productIdSet = boms.Select(x => x.ProductId).Where(id => id > 0).Distinct().ToList();
                var productDict = new Dictionary<long, (string Code, string Name)>();
                if (productIdSet.Count > 0)
                {
                    var idsJoin = string.Join(",", productIdSet);
                    var sql = $"SELECT Id, Code, Name FROM Product WHERE IsDeleted = 0 AND Id IN ({idsJoin})";
                    var products = productRepository.Query<Product>(sql);
                    foreach (var p in products)
                    {
                        productDict[p.Id] = (p.Code, p.Name);
                    }
                }

                // 映射到 DTO
                var dtoList = boms.Select(b => new BomListItemDto
                {
                    Id = b.Id,
                    Code = b.Code,
                    Name = b.Name,
                    Version = b.Version,
                    Unit = b.Unit,
                    Status = b.Status,
                    RevisionNotes = b.RevisionNotes,
                    ProductId = b.ProductId,
                    ProductCode = productDict.TryGetValue(b.ProductId, out var pv) ? pv.Code : null,
                    ProductName = productDict.TryGetValue(b.ProductId, out var pv2) ? pv2.Name : b.ProductName
                }).ToList();

                result.Code = APIEnums.Success;
                result.PageDatas = dtoList;
                result.TotalCount = total;
                result.Msg = "获取BOM分页成功";
            }
            catch (OperationCanceledException)
            {
                logger.LogWarning("获取BOM分页被取消");
                result.Code = APIEnums.Error;
                result.Msg = "请求已取消";
                result.PageDatas = new List<BomListItemDto>();
                result.TotalCount = 0;
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "获取BOM分页失败: {Message}", ex.Message);
                result.Code = APIEnums.Error;
                result.Msg = "获取BOM分页失败";
                result.PageDatas = new List<BomListItemDto>();
                result.TotalCount = 0;
            }

            return Task.FromResult(result);
        }
    }
}
